package cn.tedu.csmall.product.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
public class TimerAspect {

    // 关于ProceedingJoinPoint
    // 必须调用proceed()方法，表示执行表达式匹配到的方法
    // 调用proceed()方法必须获取返回值，且作为当前方法的返回值，表示返回表达式匹配的方法的返回值
    // 调用proceed()方法时的异常必须抛出，不可以使用try...catch进行捕获并处理
    // ---------------------------------------------------
    //关于execution表达式：用于匹配在何时执行AOP相关代码
    //表达式中的星号：匹配任意内容，只能匹配1次
    //表达式中的2个连续的小数点：匹配任意内容，可以匹配0~N次，只能用于包名和参数列表部分
    //表达式中的包是根包，会自动包含其子孙包中的匹配项
    @Around("execution(* cn.tedu.csmall.product.service.*.*(..))")
    //                 👆无论方法返回值类型是什么
    //                                                  👆无论是哪个类
    //                                                    👆无论是哪个方法
    //                                                      👆2个小数点表示任何参数列表
    public Object xxx(ProceedingJoinPoint pjp) throws Throwable {
        log.debug("执行了TimerAspect方法...");

        Signature signature = pjp.getSignature();
        Object target = pjp.getTarget();
        Object[] args = pjp.getArgs();
        Object aThis = pjp.getThis();
        log.debug("signature={}",signature);//方法名和返回值类型 例如；void cn.tedu.csmall.product.service.impl.BrandServiceImpl.rebuildCache()
        log.debug("target={}",target);//类名cn.tedu.csmall.product.service.impl.BrandServiceImpl@79476a4e
        log.debug("args={}",args);//参数
        log.debug("aThis={}",aThis);//cn.tedu.csmall.product.service.impl.BrandServiceImpl@79476a4e

        long start = System.currentTimeMillis();
        Object result = pjp.proceed();
        long end = System.currentTimeMillis();
        log.debug("【{}】类型的对象调用了【{}】方法，方法的参数值为【{}】",pjp.getTarget().getClass().getName(),pjp.getSignature().getName(),pjp.getArgs());
        log.debug("执行耗时{}毫秒", end-start);
        return result;//返回pjp.proceed方法执行的结果
    }
}
